"""
Word document parser using python-docx
"""
import time
from pathlib import Path
from typing import Union, List
import logging

try:
    from docx import Document
    from docx.shared import Inches
except ImportError:
    Document = None

from .base import FileParser, ParseResult, FileType

logger = logging.getLogger(__name__)


class WordParser(FileParser):
    """
    Parser for Word documents using python-docx
    """
    
    def __init__(self, max_file_size: int = 50 * 1024 * 1024):
        super().__init__(max_file_size)
        
        if Document is None:
            raise ImportError("python-docx is required for Word parsing. Install with: pip install python-docx")
    
    def supports_file_type(self, file_type: FileType) -> bool:
        """Check if parser supports Word documents"""
        return file_type == FileType.WORD
    
    def parse(self, file_path: Union[str, Path]) -> ParseResult:
        """
        Parse Word document and extract text content
        
        Args:
            file_path: Path to the Word document
            
        Returns:
            ParseResult with extracted text and metadata
        """
        start_time = time.time()
        file_path = Path(file_path)
        
        # Validate file
        if not self.validate_file(file_path):
            return self.create_error_result("File validation failed", file_path)
        
        try:
            # Load document
            doc = Document(str(file_path))
            
            content_parts = []
            metadata = {}
            
            # Extract core properties
            core_props = doc.core_properties
            if core_props:
                metadata.update({
                    "title": core_props.title or "",
                    "author": core_props.author or "",
                    "subject": core_props.subject or "",
                    "keywords": core_props.keywords or "",
                    "category": core_props.category or "",
                    "comments": core_props.comments or "",
                    "created": str(core_props.created) if core_props.created else "",
                    "modified": str(core_props.modified) if core_props.modified else "",
                    "last_modified_by": core_props.last_modified_by or "",
                    "revision": core_props.revision or 0,
                })
            
            # Extract paragraph text
            paragraph_count = 0
            for paragraph in doc.paragraphs:
                text = paragraph.text.strip()
                if text:
                    content_parts.append(text)
                    paragraph_count += 1
            
            metadata["paragraph_count"] = paragraph_count
            
            # Extract table content
            table_count = len(doc.tables)
            metadata["table_count"] = table_count
            
            if table_count > 0:
                content_parts.append("\n\n--- Tables ---\n")
                
                for table_idx, table in enumerate(doc.tables):
                    content_parts.append(f"\nTable {table_idx + 1}:\n")
                    
                    # Extract table data
                    table_data = []
                    for row in table.rows:
                        row_data = []
                        for cell in row.cells:
                            cell_text = cell.text.strip().replace('\n', ' ').replace('\t', ' ')
                            row_data.append(cell_text)
                        if any(cell.strip() for cell in row_data):  # Skip empty rows
                            table_data.append(row_data)
                    
                    # Format table as text
                    if table_data:
                        # Use first row as headers if it looks like headers
                        if len(table_data) > 1:
                            headers = table_data[0]
                            data_rows = table_data[1:]
                            
                            # Simple table formatting
                            content_parts.append(" | ".join(headers))
                            content_parts.append("\n" + "-" * (len(" | ".join(headers))) + "\n")
                            
                            for row in data_rows:
                                content_parts.append(" | ".join(row) + "\n")
                        else:
                            # Single row table
                            content_parts.append(" | ".join(table_data[0]) + "\n")
                    
                    content_parts.append("\n")
            
            # Count images/shapes
            image_count = 0
            for rel in doc.part.rels.values():
                if "image" in rel.target_ref:
                    image_count += 1
            
            metadata["image_count"] = image_count
            if image_count > 0:
                content_parts.append(f"\n\n--- Document contains {image_count} images ---\n")
            
            # Extract headers and footers
            header_footer_text = []
            
            for section in doc.sections:
                # Extract header text
                if section.header:
                    for paragraph in section.header.paragraphs:
                        text = paragraph.text.strip()
                        if text and text not in header_footer_text:
                            header_footer_text.append(f"Header: {text}")
                
                # Extract footer text
                if section.footer:
                    for paragraph in section.footer.paragraphs:
                        text = paragraph.text.strip()
                        if text and text not in header_footer_text:
                            header_footer_text.append(f"Footer: {text}")
            
            if header_footer_text:
                content_parts.append("\n\n--- Headers/Footers ---\n")
                content_parts.extend(header_footer_text)
            
            metadata["has_headers_footers"] = len(header_footer_text) > 0
            
            # Combine all content
            full_content = "\n".join(content_parts)
            
            if not full_content.strip():
                return self.create_error_result("No text content found in Word document", file_path)
            
            processing_time = time.time() - start_time
            
            return self.create_success_result(
                content=full_content,
                file_path=file_path,
                file_type=FileType.WORD,
                processing_time=processing_time,
                additional_metadata=metadata
            )
            
        except Exception as e:
            error_msg = f"Error parsing Word document: {str(e)}"
            logger.error(error_msg)
            return self.create_error_result(error_msg, file_path)
    
    def extract_paragraphs_only(self, file_path: Union[str, Path]) -> ParseResult:
        """
        Extract only paragraph text, skipping tables and headers/footers
        
        Args:
            file_path: Path to the Word document
            
        Returns:
            ParseResult with paragraph text only
        """
        start_time = time.time()
        file_path = Path(file_path)
        
        if not self.validate_file(file_path):
            return self.create_error_result("File validation failed", file_path)
        
        try:
            doc = Document(str(file_path))
            
            # Extract only paragraph text
            paragraphs = []
            for paragraph in doc.paragraphs:
                text = paragraph.text.strip()
                if text:
                    paragraphs.append(text)
            
            content = "\n\n".join(paragraphs)
            
            if not content.strip():
                return self.create_error_result("No paragraph text found in Word document", file_path)
            
            processing_time = time.time() - start_time
            
            metadata = {
                "paragraph_count": len(paragraphs),
                "extraction_type": "paragraphs_only"
            }
            
            return self.create_success_result(
                content=content,
                file_path=file_path,
                file_type=FileType.WORD,
                processing_time=processing_time,
                additional_metadata=metadata
            )
            
        except Exception as e:
            error_msg = f"Error extracting paragraphs: {str(e)}"
            logger.error(error_msg)
            return self.create_error_result(error_msg, file_path)
    
    def extract_tables_only(self, file_path: Union[str, Path]) -> List[List[List[str]]]:
        """
        Extract only table data as structured format
        
        Args:
            file_path: Path to the Word document
            
        Returns:
            List of tables, each table is a list of rows, each row is a list of cells
        """
        file_path = Path(file_path)
        
        if not self.validate_file(file_path):
            return []
        
        try:
            doc = Document(str(file_path))
            tables_data = []
            
            for table in doc.tables:
                table_data = []
                for row in table.rows:
                    row_data = []
                    for cell in row.cells:
                        cell_text = cell.text.strip().replace('\n', ' ').replace('\t', ' ')
                        row_data.append(cell_text)
                    table_data.append(row_data)
                
                if table_data:  # Only add non-empty tables
                    tables_data.append(table_data)
            
            return tables_data
            
        except Exception as e:
            logger.error(f"Error extracting tables: {e}")
            return []
    
    def get_document_info(self, file_path: Union[str, Path]) -> dict:
        """
        Get Word document metadata without extracting content
        
        Args:
            file_path: Path to the Word document
            
        Returns:
            Dictionary with document metadata
        """
        file_path = Path(file_path)
        
        try:
            doc = Document(str(file_path))
            
            info = {
                "paragraph_count": len(doc.paragraphs),
                "table_count": len(doc.tables),
            }
            
            # Count images
            image_count = 0
            for rel in doc.part.rels.values():
                if "image" in rel.target_ref:
                    image_count += 1
            info["image_count"] = image_count
            
            # Extract core properties
            core_props = doc.core_properties
            if core_props:
                info.update({
                    "title": core_props.title or "",
                    "author": core_props.author or "",
                    "subject": core_props.subject or "",
                    "created": str(core_props.created) if core_props.created else "",
                    "modified": str(core_props.modified) if core_props.modified else "",
                })
            
            return info
            
        except Exception as e:
            logger.error(f"Error getting document info: {e}")
            return {"error": str(e)}